/************************************************************************
 * @file PluginRequirement.h
 * @author Ian Chen
 * @version 1.0
 *
 * @section LICENSE
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details at
 * http://www.gnu.org/licenses/lgpl.html
 *
 ************************************************************************/

#ifndef PLUGINREQUIREMENT_H
#define PLUGINREQUIREMENT_H

#include <QString>
#include <QStringList>

#include <plugin/plugin_global.h>
#include <plugin/util/PluginVersion.h>

namespace antu
{
namespace plugin
{
//! Defines dependency of plugins.
/*! Defines dependency of plugins. A plugin might be dependent upon 0 or more
    other plugins, which is specified by a plugin name, and a version. For
    a dependent plugin to satisfy the dependency, the name has to match, and
    the actual dependent plugin's compatible version has to be greater than or
    equal to the version specified in PluginRequirement
 */
class PLUGINSHARED_EXPORT PluginRequirement
{
private:
    QString m_sCode;
    PluginVersion m_oVersion;
    QStringList m_arrServices;

    //! Copies content of another PluginRequirement object.
    /*! Copies content of another PluginRequirement object.

      \param requirement PluginRequirement object to copy from.
     */
    void copy(const PluginRequirement& requirement);

public:
    //! Constructor.
    /*! Constructor.

      \param name Name of dependency plugin.
      \param major Major version of dependency plugin.
      \param minor Minor version of dependency plugin.
      \param patch Patch level of dependency plugin.
      \param build Build level of dependency plugin.
     */
    PluginRequirement(const QString& code, int major, int minor, int patch, int build);

    //! Constructor.
    /*! Constructor.

      \param name Name of dependency plugin.
      \param version Version string of dependency plugin.
     */
    PluginRequirement(const QString& code, const QString& version);

    //! Constructor.
    /*! Constructor.

      \param name Name of dependency plugin.
      \param version Version of dependency plugin.
     */
    PluginRequirement(const QString& code, const PluginVersion& version);

    //! Copy constructor.
    /*! Copy constructor.

      \param requirement PluginRequirement object to be copied from.
     */
    PluginRequirement(const PluginRequirement& requirement);

    //! Name of the required plugin.
    /*! Name of the required plugin.
     */
    inline QString code() const;

    //! Version of the required plugin.
    /*! Version of the required plugin.

      \return Version of the required plugin.
     */
    inline PluginVersion requiredVersion() const;

    //! Assignment operator.
    /*! Assignment operator.

      \param requirement PluginRequirement to copy from.
      \return Returns reference to this object.
     */
    inline PluginRequirement& operator=(const PluginRequirement& requirement);

    //! == operator.
    /*! == operator.

      \return Returns true if two PluginRequirement objects are identical, false otherwise.
     */
    inline bool operator==(const PluginRequirement& requirement) const;

    inline QStringList services() const
    {
        return this->m_arrServices;
    }

    inline bool needsService(const QString& serviceName) const
    {
        return this->m_arrServices.contains(serviceName);
    }

    inline void setServices(const QStringList& services)
    {
        this->m_arrServices.clear();
        this->m_arrServices += services;
    }
};
}
}

#endif // PLUGINREQUIREMENT_H
